home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickDraw3D 1.6 SDK / Mac SampleCode New for 1.6 / CullGroupSample / Source / Objects.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-18  |  9.9 KB  |  426 lines  |  [TEXT/CWIE]

  1. /*********************************/
  2. /*    OBJECT MANAGER              */
  3. /* By Brian Greenstone           */
  4. /*********************************/
  5.  
  6.  
  7. /***************/
  8. /* EXTERNALS   */
  9. /***************/
  10. #include <QD3D.h>
  11. #include <QD3DGeometry.h>
  12. #include <QD3DGroup.h>
  13. #include <QD3DMath.h>
  14. #include <QD3DTransform.h>
  15.  
  16. #include "myglobals.h"
  17. #include "objects.h"
  18. #include "misc.h"
  19. #include "qd3d_support.h"
  20.  
  21. /****************************/
  22. /*    CONSTANTS             */
  23. /****************************/
  24.  
  25. #define INVALID_NODE_FLAG    0xffffffffL            // put into CType when node is deleted
  26.  
  27.  
  28. /**********************/
  29. /*     VARIABLES      */
  30. /**********************/
  31.  
  32.                                             // OBJECT LIST
  33. ObjNode        *gFirstNodePtr;
  34.                     
  35. ObjNode        *gCurrentNode,*gMostRecentlyAddedNode;
  36.                                         
  37. NewObjectDefinitionType    gNewObjectDefinition;
  38.  
  39. TQ3Point3D    gCoord;
  40.  
  41.  
  42. /************************ INIT OBJECT MANAGER **********************/
  43.  
  44. void InitObjectManager(void)
  45. {
  46.     gCurrentNode = nil;
  47.     gFirstNodePtr = nil;                                    // no node yet
  48.     
  49. }
  50.  
  51.  
  52. /*********************** MAKE NEW OBJECT ******************/
  53. //
  54. // MAKE NEW OBJECT & RETURN PTR TO IT
  55. //
  56. // The linked list is sorted from LARGEST z to smallest!
  57. //
  58.  
  59. ObjNode    *MakeNewObject(NewObjectDefinitionType *newObjDef)
  60. {
  61. ObjNode    *newNodePtr,*scanNodePtr,*reNodePtr;
  62. long    slot;
  63.     
  64.     slot = newObjDef->slot;
  65.     
  66.                 /* INITIALIZE NEW NODE */
  67.     
  68.     newNodePtr = (ObjNode *)AllocPtr(sizeof(ObjNode));
  69.     if (newNodePtr == nil)
  70.         DoFatalAlert("\pMakeNewObject: Alloc Ptr failed!");
  71.  
  72.     newNodePtr->SortSlot = slot;
  73.  
  74.     newNodePtr->Type = newObjDef->type;
  75.     newNodePtr->MoveCall = newObjDef->moveCall;        // save move routine
  76.     newNodePtr->Genre = newObjDef->genre;
  77.     newNodePtr->Coord = newObjDef->coord;
  78.     newNodePtr->ModeFlags = newObjDef->flags|OBJ_MODE_MOVE;
  79.     newNodePtr->RotX =
  80.     newNodePtr->RotY = 
  81.     newNodePtr->RotZ = 0;
  82.     newNodePtr->ScaleX =
  83.     newNodePtr->ScaleY = 
  84.     newNodePtr->ScaleZ = 1.0;
  85.         
  86.     newNodePtr->BaseGroup = nil;
  87.         
  88.     
  89.         
  90.                     /* FIND INSERTION PLACE FOR NODE */
  91.                     
  92.     if (gFirstNodePtr == nil)                            // special case only entry
  93.     {
  94.         gFirstNodePtr = newNodePtr;
  95.         newNodePtr->PrevNode = nil;
  96.         newNodePtr->NextNode = nil;
  97.     }
  98.     else
  99.     if (slot < gFirstNodePtr->SortSlot)                // INSERT AS FIRST NODE
  100.     {
  101.         newNodePtr->PrevNode = nil;                    // no prev
  102.         newNodePtr->NextNode = gFirstNodePtr;         // next pts to old 1st
  103.         gFirstNodePtr->PrevNode = newNodePtr;         // old pts to new 1st
  104.         gFirstNodePtr = newNodePtr;
  105.     }
  106.     else
  107.     {
  108.         reNodePtr = gFirstNodePtr;
  109.         scanNodePtr = gFirstNodePtr;
  110.             
  111.         while (scanNodePtr != nil)
  112.         {
  113.             if (slot < scanNodePtr->SortSlot)            // INSERT IN MIDDLE HERE
  114.             {
  115.                 newNodePtr->NextNode = scanNodePtr;
  116.                 newNodePtr->PrevNode = reNodePtr;
  117.                 reNodePtr->NextNode = newNodePtr;
  118.                 scanNodePtr->PrevNode = newNodePtr;            
  119.                 goto out;
  120.             }
  121.             reNodePtr = scanNodePtr;
  122.             scanNodePtr=(ObjNode *)scanNodePtr->NextNode;    // try next node
  123.         } 
  124.     
  125.         newNodePtr->NextNode = nil;                            // TAG TO END
  126.         newNodePtr->PrevNode = reNodePtr;
  127.         reNodePtr->NextNode = newNodePtr;        
  128.     }
  129.  
  130. out:
  131.     gMostRecentlyAddedNode = newNodePtr;                    // remember this
  132.     return(newNodePtr);
  133. }
  134.  
  135.  
  136. /*******************************  MOVE OBJECTS **************************/
  137.  
  138. void MoveObjects(void)
  139. {
  140. ObjNode        *thisNodePtr;
  141.     
  142.             
  143.     if (gFirstNodePtr == nil)                                // see if there are any objects
  144.         return;
  145.  
  146.     thisNodePtr = gFirstNodePtr;
  147.     
  148.     do
  149.     {
  150.                     /* NEXT TRY TO MOVE IT */
  151.                     
  152.         if ((thisNodePtr->ModeFlags & OBJ_MODE_MOVE) && (thisNodePtr->MoveCall != nil))
  153.         {
  154.             gCurrentNode = thisNodePtr;                        // set current object node
  155.             thisNodePtr->MoveCall();                        // call object's move routine
  156.         }
  157.             
  158.         thisNodePtr = (ObjNode *)thisNodePtr->NextNode;        // next node
  159.     }
  160.     while (thisNodePtr != nil);
  161.  
  162. }
  163.  
  164. /**************************** DRAW OBJECTS ***************************/
  165.  
  166. void DrawObjects(QD3DSetupOutputType *viewInfo)
  167. {
  168. ObjNode        *theNode;
  169. TQ3Status    myStatus;
  170.  
  171.     if (gFirstNodePtr == nil)                // see if there are any objects
  172.         return;
  173.  
  174.     theNode = gFirstNodePtr;
  175.  
  176.     
  177.                     /* MAIN NODE TASK LOOP */
  178.             
  179.     do
  180.     {
  181.         if (theNode->BaseGroup)                // see if group exists
  182.         {                
  183.             myStatus = Q3Object_Submit(theNode->BaseGroup,viewInfo->viewObject);
  184.             if ( myStatus == kQ3Failure )
  185.                 DoFatalAlert("\p Drawing Q3Object_Submit Failed!");
  186.         }
  187.         theNode = (ObjNode *)theNode->NextNode;
  188.     }while (theNode != nil);
  189. }
  190.  
  191.  
  192. /******************** DELETE ALL OBJECTS ********************/
  193.  
  194. void DeleteAllObjects(void)
  195. {
  196.     while (gFirstNodePtr != nil)
  197.         DeleteObject(gFirstNodePtr);
  198. }
  199.  
  200.  
  201. /************************ DELETE OBJECT ****************/
  202.  
  203. void DeleteObject(ObjNode    *theNode)
  204. {
  205. ObjNode *tempNode;
  206.  
  207.     if (theNode == nil)                                // see if passed a bogus node
  208.         return;
  209.  
  210.             /* PURGE SPECIAL DATA */
  211.             
  212.     if(theNode->BaseGroup)
  213.     {
  214.         Q3Object_Dispose(theNode->BaseGroup);
  215.         theNode->BaseGroup = nil;    
  216.     }
  217.             
  218.                     /* DO NODE SWITCHING */
  219.  
  220.     if (theNode->PrevNode == nil)                    // special case 1st node
  221.     {
  222.         gFirstNodePtr = (ObjNode *)theNode->NextNode;        
  223.         tempNode = (ObjNode *)theNode->NextNode;
  224.         tempNode->PrevNode = nil;
  225.     }
  226.     else if (theNode->NextNode == nil)                // special case last node
  227.     {
  228.         tempNode = (ObjNode *)theNode->PrevNode;
  229.         tempNode->NextNode = nil;
  230.     }
  231.     else                                            // generic middle deletion
  232.     {
  233.         tempNode = (ObjNode *)theNode->PrevNode;
  234.         tempNode->NextNode = theNode->NextNode;
  235.         tempNode = (ObjNode *)theNode->NextNode;
  236.         tempNode->PrevNode = theNode->PrevNode;
  237.     }
  238.     
  239.     DisposePtr((Ptr)theNode);        
  240. }
  241.  
  242.  
  243. /********************** GET OBJECT INFO *********************/
  244.  
  245. void GetObjectInfo(ObjNode *theNode)
  246. {
  247.     gCoord = theNode->Coord;
  248. }
  249.  
  250. /********************** UPDATE OBJECT *********************/
  251.  
  252. void UpdateObject(ObjNode *theNode)
  253. {
  254.     theNode->Coord = gCoord;
  255. }
  256.  
  257.  
  258. /************* MAKE NEW DISPLAY GROUP OBJECT *************/
  259.  
  260. ObjNode *MakeNewDisplayGroupObject(NewObjectDefinitionType *newObjDef)
  261. {
  262. ObjNode    *newObj;
  263.  
  264.     newObjDef->genre = DISPLAY_GROUP_GENRE;
  265.  
  266.     newObj = MakeNewObject(newObjDef);        
  267.     if (newObj == nil)
  268.         return(nil);
  269.  
  270.     CreateBaseGroup(newObj);
  271.     return(newObj);
  272. }
  273.  
  274.  
  275. /************************* ADD GEOMETRY TO DISPLAY GROUP OBJECT ***********************/
  276. //
  277. // Attaches a geometry object to the BaseGroup object. MakeNewDisplayGroupObject must have already been
  278. // called which made the group & transforms.
  279. //
  280.  
  281. void AttachGeometryToDisplayGroupObject(ObjNode *theNode, TQ3GeometryObject geometry)
  282. {
  283. TQ3GroupPosition    groupPosition;
  284.  
  285.     groupPosition = Q3Group_AddObject(theNode->BaseGroup,geometry);
  286.     if (groupPosition == nil)
  287.         DoFatalAlert("\pError: AttachGeometryToDisplayGroupObject");
  288. }
  289.  
  290.  
  291. /***************** CREATE BASE GROUP **********************/
  292. //
  293. // the base group contains the base translation/rotation transforms
  294. // plus the link to the heirarchial chain of joint objects if its a skeleton object.
  295. //
  296. // NOTE: this is not only used for skeleton objects, but also for display group objects!!!
  297. //
  298.  
  299. void CreateBaseGroup(ObjNode *theNode)
  300. {
  301. TQ3GroupPosition        myGroupPosition;
  302. TQ3Matrix4x4            transMatrix,scaleMatrix;
  303. TQ3TransformObject        transObject;
  304.  
  305.  
  306.     if (theNode->BaseGroup)                        // nuke old one
  307.         Q3Object_Dispose(theNode->BaseGroup);
  308.         
  309.  
  310.                 /* CREATE THE GROUP OBJECT */
  311.                 
  312.     theNode->BaseGroup = Q3DisplayGroup_New();
  313.     if (theNode->BaseGroup == nil)
  314.         DoFatalAlert("\p Couldnt allocate BaseGroup!");
  315.  
  316.  
  317.                     /* SETUP BASE MATRIX */
  318.             
  319.     Q3Matrix4x4_SetRotate_XYZ(&theNode->BaseTransformMatrix,        // init rotation matrix
  320.                                  theNode->RotX, theNode->RotY,
  321.                                  theNode->RotZ);
  322.  
  323.     Q3Matrix4x4_SetTranslate(&transMatrix, theNode->Coord.x, theNode->Coord.y,    // make translate matrix
  324.                              theNode->Coord.z);
  325.  
  326.     Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix,                // mult rot & trans matrices
  327.                          &transMatrix,
  328.                          &theNode->BaseTransformMatrix);
  329.  
  330.     Q3Matrix4x4_SetScale(&scaleMatrix, theNode->ScaleX,
  331.                          theNode->ScaleY,
  332.                          theNode->ScaleZ);
  333.  
  334.     Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix,                // mult rot & trans matrices
  335.                          &scaleMatrix,
  336.                          &theNode->BaseTransformMatrix);
  337.  
  338.  
  339.                     /* CREATE A MATRIX XFORM */
  340.  
  341.     transObject = Q3MatrixTransform_New(&theNode->BaseTransformMatrix);
  342.     myGroupPosition = Q3Group_AddObject(theNode->BaseGroup, transObject);    // add to base group
  343.     if (myGroupPosition == 0)
  344.         DoFatalAlert("\pQ3Group_AddObject Failed!");
  345.     theNode->BaseTransformObject = transObject;                                // keep illegal ref
  346.     Q3Object_Dispose(transObject);
  347.  
  348.  
  349. }
  350.  
  351. /****************** UPDATE OBJECT TRANSFORMS *****************/
  352. //
  353. // This updates the skeleton object's base translate & rotate transforms
  354. //
  355.  
  356. void UpdateObjectTransforms(ObjNode *theNode)
  357. {
  358. TQ3Matrix4x4    scaleMatrix;
  359.  
  360.  
  361.                     /* RESET BASE MATRIX */
  362.             
  363.     Q3Matrix4x4_SetRotate_XYZ(&theNode->BaseTransformMatrix,        // init rotation matrix
  364.                                  theNode->RotX, theNode->RotY,
  365.                                  theNode->RotZ);
  366.  
  367.     TranslateObjectBaseMatrixByXYZ(theNode);
  368.                             
  369.                             
  370.     Q3Matrix4x4_SetScale(&scaleMatrix, theNode->ScaleX,        // do scale
  371.                          theNode->ScaleY,
  372.                          theNode->ScaleZ);
  373.     TransformObjectBaseMatrix(theNode,&scaleMatrix);
  374.                             
  375.     SetObjectTransformMatrix(theNode);
  376. }
  377.  
  378.  
  379. /***************** SET OBJECT TRANSFORM MATRIX *******************/
  380. //
  381. // This call simply resets the base transform object so that it uses the latest
  382. // base transform matrix
  383. //
  384.  
  385. void SetObjectTransformMatrix(ObjNode *theNode)
  386. {
  387. TQ3Status                 error;
  388.  
  389.     error = Q3MatrixTransform_Set(theNode->BaseTransformObject,&theNode->BaseTransformMatrix);
  390.     if (error != kQ3Success)
  391.         DoFatalAlert("\pQ3MatrixTransform_Set Failed!");
  392. }
  393.  
  394.  
  395. /******************** TRANSLATE OBJECT BASE MATRIX BY X/Y/Z  *******************/
  396.  
  397. void TranslateObjectBaseMatrixByXYZ(ObjNode *theNode)
  398. {
  399. TQ3Matrix4x4            transMatrix;
  400.  
  401.     Q3Matrix4x4_SetTranslate(&transMatrix, theNode->Coord.x, theNode->Coord.y,    // make translate matrix
  402.                              theNode->Coord.z);
  403.                              
  404.     TransformObjectBaseMatrix(theNode,&transMatrix);
  405. }
  406.  
  407.  
  408.  
  409. /***************** TRANSFORM OBJECT BASE MATRIX ******************/
  410. //
  411. // This multiplies the current BaseTransformMatrix by the input transform matrix.
  412. //
  413.  
  414. void TransformObjectBaseMatrix(ObjNode *theNode, TQ3Matrix4x4 *inMatrix)
  415. {
  416.     Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix,    
  417.                          inMatrix,
  418.                          &theNode->BaseTransformMatrix);
  419. }
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.